package com.ray.lic;

import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.ray.log.WebLogAspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

@Component
public class License {

	private final static Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

	@Value("${server.port}")
	private String port;

	@Value("${rayboot.app_id:test}")
	private String app_id;

	@Value("${rayboot.license:test}")
	private String license;
	/**
	 * 获取CPU序列号
	 * @return
	 */
	public static String getCPUSerial() {
		String result = "";
		try {
			if(isWindows()) {
				File file = File.createTempFile("tmp", ".vbs");
				file.deleteOnExit();
				FileWriter fw = new FileWriter(file);
				String vbs = "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
						+ "Set colItems = objWMIService.ExecQuery _ \n"
						+ "   (\"Select * from Win32_Processor\") \n"
						+ "For Each objItem in colItems \n"
						+ "    Wscript.Echo objItem.ProcessorId \n"
						+ "    exit for  ' do the first cpu only! \n" + "Next \n";
	 
				// + "    exit for  \r\n" + "Next";
				fw.write(vbs);
				fw.close();
				String path = file.getPath().replace("%20", " ");
				Process p = Runtime.getRuntime().exec(
						"cscript //NoLogo " + path);
				BufferedReader input = new BufferedReader(new InputStreamReader(
						p.getInputStream()));
				String line;
				while ((line = input.readLine()) != null) {
					result += line;
				}
				input.close();
				file.delete();
			}else {
				String[] cmdA = { "/bin/sh", "-c", "dmidecode -s system-serial-number" };
				Process process = Runtime.getRuntime().exec(cmdA);
				LineNumberReader br = new LineNumberReader(new InputStreamReader(process.getInputStream()));
				StringBuffer sb = new StringBuffer();
				String line;
				while ((line = br.readLine()) != null) {
					line = line.trim();
					sb.append(line).append("\n");
				}
				result = sb.toString();
			}
		} catch (Exception e) {
			e.fillInStackTrace();
		}
		if (result.trim().length() < 1 || result == null) {
			result = "无CPU_ID被读取";
		}
		return result.trim();
	}
	
	/**
	 * 获取主板序列号
	 * @return
	 */
	public static String getMotherboardSN() {
		String result = "";
		try {
			if(isWindows()) {
				File file = File.createTempFile("realhowto", ".vbs");
				file.deleteOnExit();
				FileWriter fw = new FileWriter(file);
	 
				String vbs = "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
						+ "Set colItems = objWMIService.ExecQuery _ \n"
						+ "   (\"Select * from Win32_BaseBoard\") \n"
						+ "For Each objItem in colItems \n"
						+ "    Wscript.Echo objItem.SerialNumber \n"
						+ "    exit for  ' do the first cpu only! \n" + "Next \n";
	 
				fw.write(vbs);
				fw.close();
				String path = file.getPath().replace("%20", " ");
				Process p = Runtime.getRuntime().exec(
						"cscript //NoLogo " + path);
				BufferedReader input = new BufferedReader(new InputStreamReader(
						p.getInputStream()));
				String line;
				while ((line = input.readLine()) != null) {
					result += line;
				}
				input.close();
			}else {
				String maniBord_cmd = "dmidecode | grep 'Serial Number' | awk '{print $3}' | tail -1";
		        Process p;
	            p = Runtime.getRuntime().exec(new String[]{"sh", "-c", maniBord_cmd});// 管道
	            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
	            String line;
	            while ((line = br.readLine()) != null) {
	                result += line;
	                break;
	            }
	            br.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result.trim();
	}
	
	public boolean verify() {
		String serial = License.getCPUSerial()+"ray_"+port+License.getMotherboardSN();
		String pubKey = app_id;
		try {
			String l = license;
			pubKey = pubKey.substring(0, 20)+pubKey.substring(52);
			String reqCode = RSAEncrypt.encrypt_pub(serial, pubKey);
			if(license!=null && !"".equals(license)) {
				try {
					String license = RSAEncrypt.decrypt_pub(l, pubKey);
			        if(serial.trim().equals(license.split("#")[0].trim())) {
			        	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			        	Date now = sdf.parse(sdf.format(new Date()));
			        	Date lDate = sdf.parse(license.split("#")[1]);
			        	if(lDate.compareTo(now)!=-1) {
			        		return true;
			        	}else {
							printCode(reqCode);
				        	return false;
			        	}
			        }else {
						printCode(reqCode);
			        	return false;
			        }
				} catch (Exception e) {
					printCode(reqCode);
		        	return false;
				}
				
			}else {
				printCode(reqCode);
				return false;
			}
		} catch (Exception e) {
			logger.error("==============================");
			logger.error("=您的系统唯一ID有误，请联系服务商！=");
			logger.error("==============================");
			return false;
		}
	}

	public static void printCode(String reqCode){
		logger.error("==============================");
		logger.error("您的license并未对本机授权！");
		logger.error("联系人：雷磊 电话：18580633334 微信：Raycto");
		logger.error("请将如下申请码提供给您的服务商进行授权");
		logger.error(reqCode);
		logger.error("==============================");
	}
	
	public boolean actionVerify() {
		try {
			String l = license;
			String pubKey = app_id;
			pubKey = pubKey.substring(0, 20)+pubKey.substring(52);
			String license = RSAEncrypt.decrypt_pub(l, pubKey);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	    	Date now = sdf.parse(sdf.format(new Date()));
	    	Date lDate = sdf.parse(license.split("#")[1]);
	    	if(lDate.compareTo(now)!=-1) {
	    		return true;
	    	}else {
				logger.error("您的license已过期，重启服务获取申请码！");
	        	return false;
	    	}
		} catch (Exception e) {
			logger.error("您的license有误！");
			return false;
		}
	}
	
	public static boolean isWindows() {
        String osName = System.getProperty("os.name");
        return osName != null && osName.startsWith("Windows");
    }
	
}
